package cn.jasonfu.cyan.rest;

import cn.jasonfu.cyan.rest.api.User;
import java.io.IOException;
import java.net.URI;
import java.util.Date;
import java.util.function.Consumer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;
import reactor.core.publisher.MonoSink;

/**
 * @author jasonfu
 * @date 2021/8/19 16:28
 */
@Slf4j
@RestController
@RequestMapping("/http")
public class HttpRestController {

    @GetMapping("/redirect")
    public Mono<ResponseEntity<?>> redirect(UriComponentsBuilder uriBuilder) {
        URI uri = uriBuilder.path("/http/get/jasonfu").build().toUri();
        log.info("uri={}", uri);
        HttpHeaders headers = new HttpHeaders();
        headers.setLocation(uri);
        return Mono.just(new ResponseEntity<>(headers, HttpStatus.FOUND));
    }

    @GetMapping("/get/{id}")
    public Mono<User> get(@PathVariable String id) {
        log.info("id={}", id);
        return Mono.create(monoSink -> monoSink.success(new User("jasonfu", 18, new Date())));
    }

    @GetMapping("/get")
    public Mono<User> get(
            @RequestParam(required = false) String name,
            @RequestParam(required = false) Integer age,
            @RequestParam(required = false) Date birthday
    ) {
        log.info("name={}|age={}|birthday={}", name, age, birthday);
        return Mono.just(new User(name, age, birthday));
    }

    @PostMapping(value = "/post", params = "type=form")
    public Mono<User> postForm(
            @RequestParam(required = false) String name,
            @RequestParam(required = false) Integer age,
            @RequestParam(required = false) Date birthday
    ) {
        log.info("name={}|age={}|birthday={}", name, age, birthday);
        return Mono.just(new User(name, age, birthday));
    }

    @PostMapping(value = "/post", params = "type=body")
    public Mono<User> postBody(@RequestBody User user) {
        log.info("name={}|age={}|birthday={}", user.getName(), user.getBirthday(), user.getBirthday());
        return Mono.just(user);
    }

    @PostMapping(value = "/post", params = "type=upload")
    public Mono<String> postUpload(@RequestParam(required = false) String id, @RequestParam MultipartFile file) throws IOException {
        log.info("id={}|fileName={}", id, file.getOriginalFilename());
        byte[] bytes = file.getBytes();
        String msg = new String(bytes);
        log.info("fileContent={}", msg);
        return Mono.just("SUCCESS");
    }

    @PutMapping(value = "/put", params = "type=form")
    public Mono<String> putForm(
            @RequestParam(required = false) String name,
            @RequestParam(required = false) Integer age,
            @RequestParam(required = false) Date birthday
    ) {
        log.info("name={}|age={}|birthday={}", name, age, birthday);
        return Mono.just("SUCCESS");
    }

    @PutMapping(value = "/put", params = "type=body")
    public Mono<String> putBody(@RequestBody User user) {
        log.info("name={}|age={}|birthday={}", user.getName(), user.getBirthday(), user.getBirthday());
        return Mono.just("SUCCESS");
    }

    @DeleteMapping("/delete/{id}")
    public Mono<String> delete(@PathVariable String id) {
        log.info("id={}", id);
        return Mono.just("SUCCESS");
    }
}
